今天的目標很明顯了
會介紹Fast API
其中會想跟大家探討
其實網頁後端框架千百種光是程式語言(C#、PHP、Nodejs、Go...)
就有很多對手在跟python打架了
為什麼會想選Python的Fast API
1.評估框架的選擇
2.Fast API 起手式
在決定使用哪個後端框架時,應綜合考慮專案需求
、技術支援
、團隊背景
、效能
及生態系統
等因素。這樣可以確保所選技術不僅能滿足當前需求,還能為未來的增長和變化提供足夠的支持。
功能需求:明確了解專案的功能需求,例如是否需要即時通訊、數據處理或是高並發支持。這將幫助您選擇最適合的框架。
數據類型:考慮將要處理的數據類型,某些框架在處理特定數據(如結構化或非結構化數據)上表現更佳。
社群與文檔:選擇一個有活躍社群和良好文檔支持的框架,可以獲得更多資源和幫助。例如,Django 和 Flask 在 Python 生態系統中擁有強大的社群支持。
更新頻率:框架的持續更新和維護情況,能影響到安全性和新功能的引入。
開發者經驗:團隊對特定語言或框架的熟悉程度會影響開發效率。如果團隊已經熟悉某種語言,選擇相關的框架將更為高效。
培訓需求:如果團隊需要學習新技術,這可能會增加初期開發的時間和成本。
性能測試:不同框架在性能上的表現可能有所不同。例如,Node.js 因其非阻塞 I/O 模型而在高並發情況下表現優異,而 Django 雖然功能強大,但在某些情況下可能速度較慢。
擴展性:考慮未來的擴展需求,某些框架如 Flask 提供了極大的靈活性,適合構建微服務架構。
第三方庫和工具:評估框架周圍的生態系統,包括可用的第三方庫、工具和插件。這可以加快開發過程並提高功能實現的便利性。
綜合評比我們可以得到
評估項目 | 說明 | 是否滿足 |
---|---|---|
專案需求 | FastAPI 特別適合開發RESTful API,提供簡單的路由設計與自動化文檔生成,非常適合需要API開發的專案。 | ✅ |
技術支援 | FastAPI 擁有活躍的社群支援,文檔詳細,且支持多數主流框架與資料庫,可以在技術上有良好的支援。 | ✅ |
團隊背景 | 若團隊已有Python基礎,FastAPI學習曲線較低。對於需要熟悉異步操作的情況,可能需要一定學習時間。 | ✅ |
效能 | FastAPI 使用異步I/O,性能非常高,接近Node.js、Go等其他高效能框架。適合需要處理大量並發的專案。 | ✅ |
生態系統 | FastAPI 可以輕鬆集成到Python的廣泛生態系統中,如與Pandas、SQLAlchemy等工具整合,但比Flask生態略少。 | ✅ |
前面是以1.1團隊為主,雖說只要公司or老闆一句話我們就是用XXX框架就定案了
但如果是可商量的情況下還是要做完整評估喔~!
公司需求:選擇市場上熱門、企業常用的技術或框架,可以增加求職的機會。查看各大招聘網站或技術趨勢報告(如Stack Overflow、GitHub的年報)可以幫助了解目前哪些框架最受歡迎。
實際應用:根據想進入的行業(如Web開發、數據分析、AI/ML等),選擇該領域常見的框架。例如,如果你希望進入Web開發領域,學習FastAPI、Flask、Django這類Python框架是很有幫助的。
薪資水平:研究各種技術的市場價值。通常,較新且技術需求高的框架,其開發人員薪水也會較高。根據各地區的薪資報告、招聘網站的數據,查詢特定框架的開發人員薪資範圍,可以幫助你選擇學習那些薪酬高的技術。
社群活躍度:選擇有活躍社群支持的框架可以幫助你快速學習和解決問題。框架的GitHub issues數量、Stack Overflow問答數量、官方文檔的完整度等都能反映其社群的活躍程度和技術支持的好壞。
資源多寡:是否有豐富的學習資源,如教程、書籍、線上課程、官方範例等,這將直接影響學習效率。像是FastAPI、Flask、Django等都有大量資源,適合自學者。
其他考量因素:
一些框架簡單易上手(如Flask),適合初學者。而像Django這樣的框架功能強大,但學習曲線稍陡,需要更多時間學習。
選擇有長期發展潛力的框架可以保障你未來的技術投資不會過時。例如,FastAPI因為其異步支持和高性能逐漸被更多公司採用,有良好的發展潛力。
評估項目 | 說明 | FastAPI 適合嗎? |
---|---|---|
市場需求 | FastAPI 是一個新興框架,越來越多公司採用,特別是在需要高效能的API開發上。採用公司如 Microsoft、Netflix、Uber。 | ✔️ |
技術支援 | 社群活躍度高,有豐富的文檔和教程,支持異步功能,能滿足多數現代Web開發的技術需求。 | ✔️ |
學習背景 | 如果有Python基礎,學習FastAPI相對容易,且對Django/Flask開發者友好。到這個章節相信大家都對Python熟悉了XDD | ✔️ |
效能 | FastAPI 是基於Starlette和Pydantic的異步框架,效能極高,適合構建高效能的API,性能上優於Flask和Django。 | ✔️ |
生態系統 | FastAPI 擁有完整的生態系統,與許多庫和工具(如ORM、OAuth)兼容,且與Python的其他生態如Pandas、NumPy兼容。 | ✔️ |
以上兩點都是客觀評論
接下來是我Roni主觀的選擇了~
我會根據上述兩點綜合評估選擇下面四種來學習
根據不同情境
來使用不同語言的框架來接案或是滿足老闆需求
其實這些語言能達到的都可以互通比如說
Nodejs(爬蟲) <=> Python(爬蟲)
Go(web microservice) <=> Nodejs
...但我想要把那個情境下綜合評估最強CP值最高的框架拿來用XDD
以下評論為投資理財分析,不構成投資建議!?
技術 | 適用場景 | 使用理由 |
---|---|---|
NestJS | 非同步高效能應用、微服務架構 | 基於 TypeScript,內建微服務支援,適合構建輕量且可擴展的非同步應用,並且擁有良好的 Node.js 生態整合。 |
FastAPI | 資料科學應用,API 開發 | 支援異步程式設計,與 Python 生態系統(如 Scikit-learn、Pandas 等)無縫整合,適合快速構建資料科學應用的 API。 |
Spring Boot | 企業級應用建置、微服務、大規模系統開發 | 被廣泛應用於企業級應用的後端開發,具備強大的企業工具支援,如安全性、可擴展性和資料庫集成。 |
C# (.NET Core) | 微軟技術棧整合專案,如 Azure 或 Office 365 | 與微軟生態系統整合良好,C# 和 .NET Core 支援跨平台應用,適合各種與微軟服務相關的現代應用程式開發。 |
我會簡單分成
微服務不選Go的原因是因為沒有class(作者不太喜歡繼承這個OOP特性)跟套件相對python還是少。
強調並不是Go不好,但是就跟工程師有擅長的位置,語言也有擅長的處理情境。
Python也有許多框架,選擇Fast API對某些團隊來說也不一定是最好的
但是對我來說,我需要一個專門處理資料科學、AI界接的微服務是必選一個python backend framework
那麼不希望Django學太多技術債(寧願把時間花在spring或是C#框架上)
Flask相較Fast API 也不夠快速
所以Fast 也變成首選
**軟體開發心聲 - PHP的開發者 **
就像前面說的有些人會說
沒有Golang的爆發、JAVA的生態、JS的異步處理
給人家感覺PHP就像運動選手中,跑步不快(go)、身體不夠強壯(java)、反應不夠(js)
Laravel (PHP) 並沒有不好 : 他也有適合的天地,Sass 、MVP(Minimum Viable Product)系統。
他也可以像是跳水員,優雅而且特定的展示屬於自己的舞台。
這張章節會簡介什麼是REST API 以及會使用到的必要知識。
先麻煩個未安裝相關套件吧~!!
pip install fastapi uvicorn pydantic
這個觀念我很推薦看這位大師的說明
https://www.linkedin.com/pulse/principles-best-practices-rest-api-design-omar-ismail/
這邊會精簡成只使用到必要的需求來創造API
項目 | 說明 |
---|---|
Headers | HTTP 標頭包含請求的元數據,為伺服器提供請求的額外資訊。重要標頭包括:User-Agent(發出請求的客戶端資訊)、Authorization(用於驗證身份)、Content-Type(請求體的媒介類型)、Cookie(包含用戶的會話資料) |
HTTP Methods | 指明對資源的操作類型。常見方法包括:GET(獲取資料)、POST(提交資料)、PUT(更新資源)、DELETE(刪除資源) |
URL | 指明請求的目標資源,主要包括:IP 或 Domain(資源所在的伺服器地址)、Port(端口號,HTTP 默認 80,HTTPS 默認 443)、Resource-Oriented(具體資源路徑) |
Body | 請求體用於攜帶額外資料,常見格式包括:JSON(結構化資料)、Form Data(表單數據)、File(上傳檔案) |
今天的目標很簡單
需求: 建立兩隻API(POST 跟GET )
POST API的需求是
main.py
import json
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
# 顧客資料模型
class Customer(BaseModel):
id: int
name: str
email: str
address: str = None
# 讀取顧客資料
def read_customers():
try:
with open('customer.json', 'r', encoding='utf-8') as file:
return json.load(file)
except FileNotFoundError:
return []
# 寫入顧客資料
def write_customers(customers):
with open('customer.json', 'w', encoding='utf-8') as file:
json.dump([customer for customer in customers], file, ensure_ascii=False, indent=4)
# 新增顧客
@app.post("/customers/", response_model=Customer)
async def create_customer(customer: Customer):
customers = read_customers()
# 檢查顧客ID是否已存在
if any(c['id'] == customer.id for c in customers):
raise HTTPException(status_code=400, detail="Customer ID already exists.")
customers.append(customer.dict()) # 將 Pydantic 模型轉換為字典並添加到顧客列表
write_customers(customers)
return customer
# 獲取所有顧客
@app.get("/customers/", response_model=list)
async def get_customers():
return read_customers()
執行程式碼 檔案名稱要叫做main.py
uvicorn main:app --reload
執行步驟
http://127.0.0.1:8000/customers/
Post
{
"id": 1,
"name": "王小明",
"email": "xiaoming@example.com",
"address": "台北市信義區"
}
如果成功,就代表已經學會最基本的post api了~
接下來我們來逐步講解程式碼吧~
BaseModel 允許開發者通過類定義數據結構
,並使用 Python 類型註解來指定每個屬性的類型from pydantic import BaseModel
class Customer(BaseModel):
id: int
name: str
email: str
address: str = None
當創建 BaseModel 的實例時,Pydantic 會自動檢查傳入數據的類型,並在不符合時引發錯誤
。這樣可以確保數據的一致性和正確性。
3.數據轉換
Pydantic 能夠自動將輸入數據轉換為指定的類型。例如,字符串 "123" 會被轉換為整數 123
步驟 | 描述 |
---|---|
接收請求 | 客戶端發送 POST 請求,並附帶一個 Customer 物件。 |
讀取現有資料 | 從 customer.json 中讀取現有顧客資料。 |
檢查是否存在 | 檢查是否有相同的顧客 ID,若存在,回應錯誤。 |
新增資料 | 若 ID 不存在,將新的顧客資料添加到列表中,並寫入 customer.json 。 |
回應客戶端 | 回應新增的顧客資料,根據 response_model ,以 Customer 模型格式返回給客戶端。 |
response_model=Customer 表示這個 API 端點將會以 Customer 模型作為回應格式
。這意味著,當成功新增顧客後,會以 Customer 的結構回應給客戶端。
customers = read_customers()
這行調用了 read_customers() 函數,該函數會從 customer.json 檔案中讀取現有的顧客資料,並以列表形式返回。這些資料稍後會被用來檢查是否已經存在相同的顧客 ID
。
if any(c['id'] == customer.id for c in customers):
這行使用 any() 函數來檢查是否有任何現有顧客的 id 與新的 customer.id 相同。
HTTPException 是 FastAPI 用來拋出 HTTP 錯誤的方式
,
其中 status_code=400 表示「錯誤的請求」(Bad Request),而 detail 中的訊息會傳回給客戶端。
6. customers.append(customer.dict())
這行將新的顧客資料添加到 customers 列表中。
customer.dict() 是一個 Pydantic 模型的方法
,用來將 Pydantic 模型轉換為字典格式
。這樣做是因為顧客列表中的每個顧客資料都是字典格式的,為了保持一致性,我們需要將新的顧客資料也轉換為字典。
7. write_customers(customers)
這行呼叫了 write_customers() 函數,將更新後的顧客列表寫入 customer.json 檔案中。這會覆寫原來的資料並將新的顧客資料保存在 JSON 檔案裡。
程式碼部分
@app.get("/customers/", response_model=list)
async def get_customers():
return read_customers()
操作部分
路由不變,只要改過http method變成GET
即可~!!
步驟
我們可以透過傳入id參數(比如說前面範例我把id2同樣新增一樣是王小明)
我想要把它改成John
@app.put("/customers/{customer_id}", response_model=Customer)
async def update_customer(customer_id: int, updated_customer: Customer):
customers = read_customers()
for i, customer in enumerate(customers):
if customer['id'] == customer_id:
customers[i] = updated_customer.dict()
write_customers(customers)
return updated_customer
raise HTTPException(status_code=404, detail="Customer not found")
customer.json 檔案中讀取所有現有的顧客資料
,並將其存儲在 customers 這個變數中enumerate() 函數來遍歷 customers 列表
,並同時取得顧客的索引 i
以及對應的顧客資料 customer。這樣可以方便在找到匹配的顧客時進行資料更新。刪除的邏輯跟更新很像所以我放在同一組=> 一樣是透過ID篩選到然後作操作
刪除只要傳路徑的ID
不需要pass Data到後端處理
情境比較簡單就不畫流程圖了XDD
用patch的情境帶入即可
@app.delete("/customers/{customer_id}")
async def delete_customer(customer_id: int):
customers = read_customers()
# 過濾掉需要刪除的顧客
filtered_customers = [customer for customer in customers if customer['id'] != customer_id]
if len(filtered_customers) == len(customers):
raise HTTPException(status_code=404, detail="Customer not found")
write_customers(filtered_customers)
return {"message": "Customer deleted successfully"}
列表生成式:
filtered_customers = [customer for customer in customers if customer['id'] != customer_id]
1.這行代碼創建了一個新的列表,名為 filtered_customers。
它遍歷 customers 列表中的每一個 customer。
2.條件判斷:
if customer['id'] != customer_id:
對於每個 customer,它檢查該顧客的 id 是否不等於傳入的 customer_id。
只有當條件為 True 時,該 customer 才會被包括在新的列表中。
3.過濾效果:
結果是 filtered_customers 列表只包含那些不需要被刪除的顧客。這樣可以在後續操作中用來更新顧客資料,而不包含已經刪除的顧客。
今天我們學會了
軟體評估的重要環節
HTTP Request的重要四大部分
Fast API
明天我們會使用相同的API來做界接
前端不會著墨太多
但是會帶大家看實際是怎麼橋接的~